package chapterSystem.client.interfaceDrawing.activities;

import chapterSystem.client.ChapterSystemService;
import chapterSystem.client.callbacks.LoggCallback;
import chapterSystem.client.interfaceDrawing.InterfaceProvider;
import chapterSystem.client.model.entities.BrotherEntity;
import chapterSystem.client.model.entitiesInt.Brother;
import chapterSystem.client.model.entitiesInt.Unit;
import chapterSystem.client.model.enums.ActivityType;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * User: Svetlana Zemlyanskaya(svetazem@yandex-team.ru)
 * Date: 4/22/12
 */
public class EditBrotherActivity extends Activity {
    final private Activity callbackActivity;
    final private String selected;
    final private Map<String, Unit> allUnits;

    public EditBrotherActivity(final Brother brother, final ActivityType type, final Activity callbackActivity,
                               final String selected, final Map<String, Unit> allUnits) {
        super(brother, type);
        this.callbackActivity = callbackActivity;
        this.selected = selected;
        this.allUnits = allUnits;
    }

    @Override
    public void drawActivity(final StackLayoutPanel workArea) {
        ChapterSystemService.App.getInstance().getBrotherByLogin(selected, new EditBrotherCallback(workArea));
    }

    private class EditBrotherCallback implements AsyncCallback<Brother> {
        final private StackLayoutPanel workArea;

        private EditBrotherCallback(StackLayoutPanel workArea) {
            this.workArea = workArea;
        }


        @Override
        public void onFailure(Throwable caught) {
            workArea.clear();
            workArea.add(new HTML(), new HTML("Failed to connect to server"), 4);
        }

        @Override
        public void onSuccess(final Brother result) {
            workArea.clear();
            System.out.println("Edit: " + result);

            final FlexTable table = new FlexTable();
            final VerticalPanel form = new VerticalPanel();
            form.setSize("100%", "100%");
            form.add(table);

            final InterfaceProvider interfaceProvider = InterfaceProvider.getInstance();

            final TextArea nameField = interfaceProvider.createTextField();
            nameField.setText(result.getName());
            final ListBox unitId = fillUnitList(new ArrayList<Unit>(allUnits.values()), result.getUnitId());
            final TextArea rankBattleField = interfaceProvider.createTextField();
            rankBattleField.setText(String.valueOf(result.getRankBattle()));
            final TextArea rankWork = interfaceProvider.createTextField();
            rankWork.setText(String.valueOf(result.getRankWork()));
            final TextArea pointsField = interfaceProvider.createTextField();
            pointsField.setText(String.valueOf(result.getPoints()));

            table.setText(0, 0, "Name: ");
            table.setText(1, 0, "Unit: ");
            table.setText(2, 0, "Battle Rank: ");
            table.setText(3, 0, "Work Rank: ");
            table.setText(4, 0, "Points: ");

            table.setWidget(0, 1, nameField);
            table.setWidget(1, 1, unitId);
            table.setWidget(2, 1, rankBattleField);
            table.setWidget(3, 1, rankWork);
            table.setWidget(4, 1, pointsField);

            Button submitReportButton = new Button("Submit");
            submitReportButton.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    boolean hasErrors = false;
                    System.out.println("Submit button was pushed");

                    if (nameField.getText().trim().length() == 0) {
                        hasErrors = true;
                        table.setText(0, 2, "Enter name");
                    }

                    try {
                        final int newRankBattle = Integer.parseInt(rankBattleField.getText().trim());
                        if (newRankBattle < 0) {
                            hasErrors = true;
                            table.setText(2, 2, "Must be nonnegative int");
//                        } else if (newRankBattle >= brother.getRankBattle()) {
//                            hasErrors = true;
//                            table.setText(2, 2, "Must be < your rank");
                        }
                    } catch (NumberFormatException e) {
                        hasErrors = true;
                        table.setText(2, 2, "Must be int");
                    }

                    try {
                        final int newRankWork = Integer.parseInt(rankWork.getText().trim());
                        if (newRankWork < 0) {
                            hasErrors = true;
                            table.setText(3, 2, "Must be nonnegative int");
//                        } else if (newRankWork >= brother.getRankWork()) {
//                            hasErrors = true;
//                            table.setText(3, 2, "Must be < your rank");
                        }
                    } catch (NumberFormatException e) {
                        hasErrors = true;
                        table.setText(3, 2, "Must be int");
                    }

                    try {
                        if (Integer.parseInt(pointsField.getText().trim()) < 0) {
                            hasErrors = true;
                            table.setText(4, 2, "Must be nonnegative int");
                        }
                    } catch (NumberFormatException e) {
                        hasErrors = true;
                        table.setText(4, 2, "Must be int");
                    }

                    if (hasErrors) return;

                    final Unit selectedUnit = allUnits.get(unitId.getValue(unitId.getSelectedIndex()));
                    final Brother newBrother = new BrotherEntity(result.getId(),
                            Integer.parseInt(rankBattleField.getText().trim()),
                            selectedUnit.getId(),
                            nameField.getText(),
                            Integer.parseInt(rankWork.getText().trim()), Integer.parseInt(pointsField.getText().trim()));
                    ChapterSystemService.App.getInstance().editBrother(newBrother, new SubmitEditBrotherCallback(workArea));
                    ChapterSystemService.App.getInstance().addLog(brother.getId(), id, "Edit brother: " + newBrother,
                            new LoggCallback());
                }
            });

            final HorizontalPanel buttonPanel = new HorizontalPanel();

            buttonPanel.add(submitReportButton);
//            form.add(submitReportButton);

            Button returnButton = new Button("Cancel");
            returnButton.addClickHandler(new ClickHandler() {

                @Override
                public void onClick(final ClickEvent event) {
                    EditBrotherActivity.this.callbackActivity.drawActivity(workArea);
                }
            });
            buttonPanel.add(returnButton);
//            form.add(returnButton);
            form.add(buttonPanel);

            Button seeLogButton = new Button("See Brother's Log");
            seeLogButton.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    ChapterSystemService.App.getInstance().getBrotherLog(result.getId(), new AsyncCallback<List<String>>() {
                        @Override
                        public void onFailure(Throwable caught) {
                            Window.alert(caught.getMessage());
                        }

                        @Override
                        public void onSuccess(List<String> log) {
                            addBrotherLog(workArea, log, result);
                        }
                    });
                }
            });
            form.add(seeLogButton);

            workArea.add(form, new HTML("Edit Brother"), 4);

        }

        private void addBrotherLog(final StackLayoutPanel workArea, List<String> log, Brother brother) {
            workArea.clear();
            VerticalPanel panel = new VerticalPanel();
            panel.setBorderWidth(3);
            panel.setWidth("100%");
            panel.setHeight("100%");

            for (String entry : log) {
                panel.add(new HTML(entry));
            }

            Button returnButton = new Button("<< Back");
            returnButton.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(final ClickEvent event) {
                    EditBrotherActivity.this.drawActivity(workArea);
                }
            });

            panel.add(returnButton);
            panel.setCellHorizontalAlignment(returnButton, HasAlignment.ALIGN_CENTER);
            panel.setCellVerticalAlignment(returnButton, HasAlignment.ALIGN_BOTTOM);
            workArea.add(new ScrollPanel(panel), new HTML("View Brother's " + brother.getName() + " activity"), 4);
        }

        private ListBox fillUnitList(final List<Unit> units, final int currentUnit) {
            ListBox lb = new ListBox();
            for (int i = 0; i < units.size(); i++) {
                final Unit unit = units.get(i);
                lb.addItem(unit.getName());
                if (unit.getId() == currentUnit) {
                    lb.setItemSelected(i, true);
                }
            }
            return lb;
        }
    }

     private class SubmitEditBrotherCallback implements AsyncCallback<String> {
        private StackLayoutPanel workArea;

        private SubmitEditBrotherCallback(StackLayoutPanel workArea) {
            this.workArea = workArea;
        }


        @Override
        public void onFailure(Throwable caught) {
            Window.alert("Error: " + caught.getMessage());
        }

        @Override
        public void onSuccess(String result) {
            if ("Ok".equals(result)) {
                Window.alert("Saved");
                EditBrotherActivity.this.callbackActivity.drawActivity(workArea);
            } else {
                Window.alert("Error: " + result);
            }
        }
    }
}
